eval()
function is used
improperly.
encodeURI()
and decodeURI()
encounter a malformed
URI.
Promise.any().
throw
statement.
throw
any type of object as an Exception,
such as Numbers, Strings, Arrays,
etc.
try, catch, finally
statements, which gives us control
over the flow of exceptions on our
code.
try
clause is mandatory and wraps a block
of code that potentially can throw an
error.
catch
block, which wraps JavaScript code
that handles the error.
catch
clause stops the exception from
propagating through the call stack and
allows the application flow to
continue. The error itself is passed
as an argument to the catch
clause.
instanceof
operator that can be used to
differentiate between the types of
exceptions:
throw
an exception that has been caught. For
example, if you catch an exception,
the type of which is not relevant to
you in this context.
finally
code block is executed after the try
and catch
clauses, regardless of any exceptions.
The finallyclause is useful for including clean
up code such as closing WebSocket
connections or other resources.
finally
block will be executed even if a
thrown exception is not caught. In
such a scenario, the finally
block is executed, and then the engine
continues to go through the functions
in the call stack in order until the
exception is handled properly or the
application is terminated.
finally
block will be executed even if the try
or catch
blocks execute a return
statement.
foo1()
function, we get false
as result, even though the try
block has a return
statement.
return
statement in a catch
block:
foo2()
also returns false.
{ "name": "John",
"age": 30 }; Internally, we’ll use JSON.parse.
If it receives malformed json, then it
throws SyntaxError. But even if json
is syntactically correct, that doesn’t
mean that it’s a valid user, right? It
may miss the necessary data. For
instance, it may not have name and age
properties that are essential for our
users.
async
function, a rejected promise will be
returned with the thrown error,
equivalent to:
foo()
is invoked:
foo()
is async, it dispatches a Promise. The code does not wait for the async
function, so there is no actual error
to be caught at the moment. The finally
block is executed and then the Promise
rejects.
Promise.
await
keyword when invoking foo()
and wrapping the code in an async
function:
Promise:
foo
with a string
instead of a number:
Uncaught TypeError: x is not a
number
since the catch
of the promise is not being able to
handle an error that was thrown
outside of the Promise.
try
and catch
clauses:
foo
is modified to throw an error inside
of the Promise:
catch
statement of the promise will handle
the error:
Promise
is the same thing as using the reject
callback. So it's better to
define foo
like this:
catch
method to handle the error inside the Promise, the next function from the callback
queue will be added to the
stack.
err
argument. If no error
occurred, err
will be set to null.
err
object, it's better not to touch
or rely on the result
parameter.
window.onerror
event handler that can be used for
this purpose.
Uncaught ReferenceError: foo
is not defined.
window.onerror
because it is a function assignment,
and there can only be one function
assigned to an event at a time.
window.onerror, you will override any previous
handler that might have been assigned
by third-party libraries. This can be
a huge problem, especially for tools
such as error trackers, as they will
most likely completely stop
working.
window.onerror, and simply calls it before
proceeding. Using this pattern, you
can keep adding additional handlers to window.onerror.
window
object:
process
object from the EventEmmiter
module provides two events for
handling errors.
uncaughtException
--- emitted when an uncaught
exception bubbles all the way
back to the
event loop. By default, Node.js handles
such exceptions by printing
the stack trace to stderr and
exiting with code 1. Adding a handler for this
event overrides the default
behavior. The correct use of
the event is to perform
synchronous cleanup of
allocated resources (e.g. file
descriptors, handles, etc)
before shutting down the
process. It is not safe to
resume normal operation
afterwards.
unhandledRejection
--- emitted whenever a Promise
is rejected and no error
handler is attached to the
promise within a turn of the
event loop. The unhandledRejection
event is useful for detecting
and keeping track of promises
that were rejected and which
rejections have not yet been
handled.
setTimeout
and setInterval
methods can accept?
setTimeout
method return in the Node
environment?
setTimeout
method returns a Timeout
object that can be passed to clearTimeout
to cancel the timeout.
setTimeout
method return in the browser
environment?
setTimeout
method returns a number
representing the unique ID
associated with that timeout.
The ID number can be passed to clearTimeout
to cancel the callback from
running.
test
function to be async, and we need to prepend the callack
invocation with await.
--require ./[file].js
flag allows files to be required
before executing scripts with the node
command
"Refactoring is the process of changing a software system in such a way that it does not alter the external behavior of the code yet improves its internal structure." --- Martin Fowler
UNIT TESTING is a level of software testing where individual units/ components of a software are tested. The purpose is to validate that each unit of the software performs as designed. A unit is the smallest testable part of any software. It usually has one or a few inputs and usually a single output. In procedural programming, a unit may be an individual program, function, procedure, etc. In object-oriented programming, the smallest unit is a method, which may belong to a base/ super class, abstract class or derived/ child class. See More about unit testing here
add, subtract, multiply
and you want to do it with TDD.
add
method. If we run this test, it will
fail, showing something like
this:
-1, decimal numbers 0.4, really big numbers 10000000000000000000...00
or even unexpected values like
strings, arrays, undefined
number-game-errors.html
open in, and open your
JavaScript console. You should
see an error message along the
following lines:addEventListener()]docs/Web/API/EventTarget/addEventListener).
addeventListener
to addEventListener
should fix this. Do this
now.
Null]docs/Glossary/Null) is a
special value that means
"nothing", or
"no value". So lowOrHi
has been declared and
initialised, but not with any
meaningful value --- it has no
type or value.
checkGuess() { ... }
block). As you'll learn
in more detail in our later
[functions
article]docs/Learn/JavaScript/Building_blocks/Functions),
code inside functions runs in
a separate scope than code
outside functions. In this
case, the code was not run and
the error was not thrown until
the checkGuess()
function was run by line
86.
textContent
property of the lowOrHi
constant to a text string, but
it's not working because lowOrHi
does not contain what
it's supposed to.
Let's see why this is ---
try searching for other
instances of lowOrHi
in the code. The earliest
instance you'll find in
the JavaScript is on line
48:
null
after this line has been run.
Add the following code on line
49:
console.log()]docs/Web/API/console/log) is
a really useful debugging
function that prints a value
to the console. So it will
print the value of lowOrHi
to the console as soon as we
have tried to set it in line
48.
console.log()
result in your console.
lowOrHi's value is null
at this point, so there is
definitely a problem with line
48.
document.querySelector()]docs/Web/API/Document/querySelector)
method to get a reference to
an element by selecting it
with a CSS selector. Looking
further up our file, we can
find the paragraph in
question:
.), but the selector being
passed into the querySelector()
method in line 48 has no dot.
This could be the problem! Try
changing lowOrHi
to .lowOrHi
in line 48.
console.log()
statement should return the <p>
element we want. Phew! Another
error fixed! You can delete
your console.log()
line now, or keep it to
reference later on --- your
choice.
Error
objects are thrown when runtime errors
occur. The Error
object can also be used as a base
object for user-defined exceptions.
See below for standard built-in error
types.
Error
objects being created and
thrown.
Error
constructor, there are other core
error constructors in JavaScript. For
client-side exceptions, see
Exception handling
statements.
encodeURI()
or
decodeURI()
are passed invalid parameters.
Promise.any().
Error
object.
Error.captureStackTrace()
Error.prototype.description
Error.prototype.number
addeventListener
to .addEventListener. Do this now.
randomNumber
variable, and the lines where
the random number is first
set. The instance that stores
the random number that we want
to guess at the start of the
game should be around line
number 44:
console.log()
again --- insert the following
line directly below each of
the above two lines:
randomNumber
is equal to 1 at each point
where it is logged to the
console.
Math.random()]/Math/random), which generates a
random decimal number between 0 and 1,
e.g. 0.5675493843.
Math.random()
through [Math.floor()]/Math/floor), which rounds the
number passed to it down to the
nearest whole number. We then add 1 to
that result:
checkGuess()
function:
=) --- which sets a variable to be
equal to a value --- with the strict
equality operator (===), which tests whether one value is
equal to another, and returns a true/false
result.
checkGuess():
true, causing the program to report that
the game has been won. Be
careful!
checkGuess()
function.
objects are thrown when runtime
errors occur. TheError` object can also be used as a
base object for user-defined
exceptions. See below for standard
built-in error types.
Error
objects being created and
thrown.
Error
constructor, there are other core
error constructors in JavaScript. For
client-side exceptions, see [Exception
handling
statements]Guide/Control_flow_and_error_handling#exception_handling_statements).
EvalError]/EvalError)
eval()]/eval).
RangeError]/RangeError)
ReferenceError]/ReferenceError)
SyntaxError]/SyntaxError)
TypeError]/TypeError)
URIError]/URIError)
encodeURI()]/encodeURI) or [decodeURI()]/decodeURI) are passed invalid
parameters.
AggregateError]/AggregateError)
Promise.any()]/Promise/any).
InternalError]/InternalError)
Error()]/Error/Error)
Error
object.
Error
object with the intention of raising
it using the [throw]Reference/Statements/throw) keyword.
You can handle the error using the
[try...catch]Reference/Statements/try...catch)
construct:
constructor]/Object/constructor) property or, if
you're writing for modern
JavaScript engines, [instanceof]Reference/Operators/instanceof)
keyword:
Error
objects that have more specific
messages. The original error should be
passed to the new Error
in the constructor option
parameter (cause
property), as this ensures that the
original error and stack trace are
available to higher level try/catch
blocks.
doFailSomeWay()
and doFailAnotherWay()):
cause
property in [custom error
types]/error#custom_error_types),
provided the subclasses'
constructor passes the options
parameter when calling super():
Error
to be able to throw new MyError()
and use instanceof MyError
to check the kind of error in the
exception handler. This results in
cleaner and more consistent error
handling code.
CustomError
class methods, but only when they are
declared with
[Object.defineProperty()]/Object/defineProperty).
Otherwise, old versions of Babel and
other transpilers will not correctly
handle the following code without
additional configuration.
CustomError
constructor in the stack trace when
using ES2015 classes.
http://great.jokes/christmas) that you can call to a get list of
Christmas jokes in JSON format.
apiUrl
and jokeId
which returns a promise.
id.
saySetup
and sayPunchLine
methods.
new Error('No jokes
found id:
{jokeId}').
new Error('No jokes at
url: {url}')
for an unexpected shape.
fetch(url)
function, which implements the basics
of the fetch api.
Learn about fetch.
Learn about async/await.
lint-staged
error
will exit the process and fail a
build.
warn
will continue to run the process and
not fail a build.
off
will ignore the rule entirely.
extends
property. eslint:recommended
is a built-in config.
env
property can be used to set the
environment against which files should
be evaluated.
prettier
can be used to format code in files
via CLI:
prettier
can be used to format markdown and
graphql, too.
prettier
allows for a .prettierignore
to ignore formatting of generated
files
extended eslint configs take precedence
from the end of the array.
rules
in the the eslint config take
precedence over any extensions.
prettier
can be run with a --list-different
flag which exits with a non-zero code
if there are any files that are not
formatted correctly. This can be used
with ghooks
to ensure all team members are using prettier.
--
operator:
@flow
at the top of files that you want to
use flow
to make type strict after installing flow-bin
as a dev dependency.
husky
works in a similar way to ghooks, except that you add npm scripts to
run pre and post-hooks.
lint-staged
lint-staged
not only allows linters to be run on
precommit, but allows one to define
commands to be run should linting
pass, allowing for repo owners to have
autoformatting run and changed files
staged without relying on
collaborators to have autoformatters
enabled.
thumb-war
and utils, and mock out utils.getWinner
so that we can evaluate other aspects
of thumb-war. We are making utils.getWinner
deterministic, as the randomness of
what it usually returns will affect
the outcomes of our tests in
non-deterministic ways.
jest.fn
which takes a mock implementation, and
accepts all arguments passed to
it.
mock
object where we can store calls to the
mock function.
jest.fn.
toHaveBeenCalledWith, toHaveBeenNthCalledWith, or to inspect mockFn.mock.calls
to inspect how the function was used
for all calls.
jest.spyOn
to create a mock implementation. This
mitigates us having to store the
original function and replace it, as
Jest will do the heavy lifting for
us.
jest.spyOn(myObject,
'myObjectFn')
myObject.myObjectFn.mockImplementation(mockFn)
to create a mock
implementation of myObjectFn
myObject.myObjectFn.mockRestore()
to replace the mock
implementation with the
original so that other tests
are not affected. .mockRestore()
restores the mock
implementation to its
pre-mocked definition
jest.spyOn
is still a form of monkey-patching.
Monkey-patching is great for our own
modules, because we're using
commonjs's require. When working in an es environment
we'll have to mock an entire
module, and jest.mock
allows one to do this.
jest.mock
we can create the mock implementation
inside of the mock, and no longer need
to use jest.spyOn
and [fnToMock].mockImplementation.
mock.mockRestore()
to restore the mock implementation, we
now use mock.mockReset(). mock.mockRestore()
is only available for mocks created
with jest.spyOn
jest.mock
can be placed anywhere in the file,
and Jest will hoist it to the top of
the file.
jest.mock
takes control of the entire module
requiring system. This can be
simulated using require.cache. require.cache
is an object that has keys for each
import, with each key being associated
with an object containining
information regarding the
import.
exports
property to create the mock
implementation of the module
__mocks__
folder. Node modules can be placed in
the root
__mocks__
that Jest inspects, by default
adjacent to node_modules. For user-defined modules
they can be placed in a __mocks__
folder adjacent to the module. The
mock must use the same filename as the
mocked module.
jest.mock('./path/to/mock')
must be added to the test file.
require.cache. We create a file containing the
mock, which also uses our fn
to allow us to evaluate calls. In our
test we import our mock, and then
retrieve the cached paths for the
actual utils and mock utils, rewriting require.cache's key for the actual utils with
the mocked utils.
git branch add-my-new-file git add my-new-file.js git commit -m "Add new file" git push -u origin add-my-new-file This is the typical push workflow.
git diff master feature
git diff 1fc345a 2e3dff
git diff 1fc345a 2e3dff my-file.js Time Travel checkout
git checkout master
git checkout 7d3e2f1
git checkout -
git checkout HEAD~3 Git Do-over: Reset and Rebase Git Reset : Can be used to travel back in time before a bug or error occured. --soft : appended to reset to move our HEAD ref to the commit we specified - does not touch our code, only resets commit messages.(least dangerous!) --mixed : Default state of Git reset, changes are preserved but they are removed from the commit history straight to the working directory. --hard : Adjust head ref and totally destroy any interim code changes Rebase: An Alternative Form of Time Travel